package com.jcruz.idkclient;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import android.app.Activity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class ConectariDK extends Activity {

	private static String TAG = ConectariDK.class.getName();

	// Objetos de la UI
	private EditText txIp, txPuerto, txEnviar;
	private TextView txRecibido, txEstatus;
	private Button btConectar, btCerrar, btEnviar;

	// Manejo de streams de in y out
	private Socket so = null;
	private ObjectOutputStream sout = null;
	private InputStream sbin = null;

	// Maneja el thread para lectura
	private LecturaStream tarea1;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_conectari_dk);

		if (android.os.Build.VERSION.SDK_INT > 9) {
			StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
					.permitAll().build();
			StrictMode.setThreadPolicy(policy);
		}

		txIp = (EditText) findViewById(R.id.txIp);
		txPuerto = (EditText) findViewById(R.id.txPuerto);
		txEnviar = (EditText) findViewById(R.id.txEnviar);
		txRecibido = (TextView) findViewById(R.id.txRecibido);
		txEstatus = (TextView) findViewById(R.id.txEstatus);

		btConectar = (Button) findViewById(R.id.btConectar);
		btCerrar = (Button) findViewById(R.id.btCerrar);
		btEnviar = (Button) findViewById(R.id.btEnviar);

		// Acceso al flujo de entrada via tarea asyncrona
		tarea1 = new LecturaStream();
		tarea1.execute();

		// Al pulsar conectar
		btConectar.setOnClickListener(new OnClickListener() {
			@Override
			// conectar
			public void onClick(View v) {
				Conectar();
			}
		});

		// Al pulsar enviar
		btEnviar.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Enviar();
			}
		});

		// Al pulsar desconectar
		btCerrar.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Cerrar();
			}
		});

	}

	private class LecturaStream extends AsyncTask<Void, String, Boolean> {

		@Override
		protected void onPreExecute() {
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			// Buffer para lectura de valores
			byte[] buffer = new byte[1024];
			int bytes; // number of bytes read
			// Lectura hasta cancelar la tarea
			while (!isCancelled()) {
				try {// Sin problema para el Socket ni el inputStream
					if ((sbin != null) && (so != null) && (!so.isClosed())) {
						// Leer del InputStream y guardar en el buffer
						bytes = sbin.read(buffer);
						if (bytes != -1) {
							// Indica que hay data lista para la UI
							publishProgress(new String(buffer, 0, bytes));
							// Borrar el buffer
							java.util.Arrays.fill(buffer, (byte) 0);
						}
					}
				} catch (Exception e) {
				}
			}
			return true;
		}

		@Override
		protected void onProgressUpdate(String... values) {
			// Actualiza la UI con la data recibida del stream
			txRecibido.setText(values[0]);

		}

		@Override
		protected void onPostExecute(Boolean result) {
		}

		@Override
		protected void onCancelled() {
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_conectari_dk, menu);
		return true;
	}

	// Conectamos
	public void Conectar() {
		try {// creamos sockets con los valores anteriores
			so = new Socket(txIp.getText().toString(), Integer.valueOf(txPuerto
					.getText().toString()));
			// si nos pudimos conectar
			if (so.isConnected()) {
				try {
					// Accedo a flujo de salida
					sout = new ObjectOutputStream(so.getOutputStream());
					// Acceder al flujo de entrada
					sbin = so.getInputStream();
					//Mensaje de estatus y manejo de botones
					txRecibido.setText("");
					btConectar.setEnabled(false);
					btCerrar.setEnabled(true);
					btEnviar.setEnabled(true);
					Set_txEstatus("Stream abierto... ", 1);
				} catch (IOException e) {
					Log.e(TAG, e.toString());
				}
			} else
				// error al conectarse
				// mostramos msg de error
				Set_txEstatus("Error socket .. ", 0);

		} catch (Exception e) {
			// Si hubo algun error mostramos error
			Set_txEstatus("Error al conectar...", 0);
			Log.e(TAG, e.toString());
		}
	}

	// Enviando comandos
	public boolean Enviar() {
		try {
			// si la conexion continua
			if (so.isConnected())
			{
				// Envio mensaje por flujo indicando el final con \r
				sout.writeObject(txEnviar.getText().toString() + '\r');
				// envio ok
				return true;
			} else {// en caso de que no halla conexion al enviar el msg
				Set_txEstatus("Error al enviar...", 0);// error
				return false;
			}

		} catch (IOException e) {// hubo algun error
			Set_txEstatus("Error al enviar...", 0);// error
			Log.e(TAG, e.toString());
			return false;
		}
	}

	// Desconectamos
	public void Cerrar() {
		try {
			// Cierra flujo de entrada
			if (sbin != null)
				sbin.close();
			if (sout != null)
				sout.close();
			// cerramos socket
			if (so != null)
				so.close();
			txRecibido.setText("");
			btConectar.setEnabled(true);
			btEnviar.setEnabled(false);
			btCerrar.setEnabled(false);
			Set_txEstatus("Stream cerrado...", 1);
		} catch (IOException e) {
			Set_txEstatus("Error al cerrar...", 0);// error
			Log.e(TAG, e.toString());
		}

	}

	/*
	 * Cambiamos texto de txtstatus segun parametro flag_status flag_status 0
	 * error, 1 ok
	 */
	public void Set_txEstatus(String txt, int flag_status) {
		// cambiel color
		if (flag_status == 0) {
			txEstatus.setTextColor(Color.RED);
		} else {
			txEstatus.setTextColor(Color.GREEN);
		}
		txEstatus.setText(txt);
	}

	@Override
	protected void onStop() {
		super.onStop();
		Cerrar();
	}

}
